package game;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author jb
 * 
 * Modified by Stefan
 *
 */
// TODO: Game class
public class Game {
	
	private String name;
	private Map map;
	private ArrayList< Player > players;
	
	private int turn;
	private int playerTurn;
	private boolean isStarted;
	
	private HashMap< String, BuildingType > buildingTypes;
	private HashMap< String, Integer[] > tableDamage;
	private HashMap< String, Integer > tableMovementCost;
	private ArrayList< TileType > tileTypes;
	private HashMap< String, UnitType > unitTypes;
	
	/**
	 * @param name
	 * @param map
	 * @param players
	 */
	public Game(String name, Map map, ArrayList<Player> players) {
		super();
		this.name = name;
		this.map = map;
		this.players = players;
	}

	//
	// Getters/setters
	//	
	
	/**
	 * @return Get name of game
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name Name of game
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the players
	 */
	public ArrayList<Player> getPlayers() {
		return players;
	}

	/**
	 * @param players the players to set
	 */
	public void setPlayers(ArrayList<Player> players) {
		this.players = players;
	}

	/**
	 * @return the turn
	 */
	public int getTurn() {
		return turn;
	}

	/**
	 * @param turn the turn to set
	 */
	public void setTurn(int turn) {
		this.turn = turn;
	}

	/**
	 * @return the playerTurn
	 */
	public int getPlayerTurn() {
		return playerTurn;
	}

	/**
	 * @param playerTurn the playerTurn to set
	 */
	public void setPlayerTurn(int playerTurn) {
		this.playerTurn = playerTurn;
	}

	/**
	 * @return the buildingTypes
	 */
	public HashMap< String, BuildingType > getBuildingTypes() {
		return buildingTypes;
	}

	/**
	 * @param buildingTypes the buildingTypes to set
	 */
	public void setBuildingTypes(HashMap< String, BuildingType > buildingTypes) {
		this.buildingTypes = buildingTypes;
	}

	/**
	 * @return the tableDamage
	 */
	public HashMap<String, Integer[]> getTableDamage() {
		return tableDamage;
	}

	/**
	 * @param tableDamage the tableDamage to set
	 */
	public void setTableDamage(HashMap<String, Integer[]> tableDamage) {
		this.tableDamage = tableDamage;
	}

	/**
	 * @return the tableMovementCost
	 */
	public HashMap<String, Integer> getTableMovementCost() {
		return tableMovementCost;
	}

	/**
	 * @param tableMovementCost the tableMovementCost to set
	 */
	public void setTableMovementCost(HashMap<String, Integer> tableMovementCost) {
		this.tableMovementCost = tableMovementCost;
	}

	/**
	 * @return the tileTypes
	 */
	public ArrayList<TileType> getTileTypes() {
		return tileTypes;
	}

	/**
	 * @param tileTypes the tileTypes to set
	 */
	public void setTileTypes(ArrayList<TileType> tileTypes) {
		this.tileTypes = tileTypes;
	}

	/**
	 * @return the unitTypes
	 */
	public HashMap<String, UnitType> getUnitTypes() {
		return unitTypes;
	}

	/**
	 * @param unitTypes the unitTypes to set
	 */
	public void setUnitTypes(HashMap<String, UnitType> unitTypes) {
		this.unitTypes = unitTypes;
	}

	/**
	 * @return the map
	 */
	public Map getMap() {
		return map;
	}
	
	/**
	 * @param map the map to set
	 */
	public void setMap(Map map) {
		this.map = map;
	}
	
	/**
	 * @return the isStarted
	 */
	public boolean isStarted() {
		return isStarted;
	}

	/**
	 * @param isStarted the isStarted to set
	 */
	public void setStarted(boolean isStarted) {
		this.isStarted = isStarted;
	}

	//
	// Low level commands
	//

	public void setTile(boolean server, int x, int y, int tile)
	{
		map.setTile(x, y, tile);
	}
	
	public void placeUnit(boolean server, Unit unit) 
	{
		map.addUnit(unit);
	}
	
	public void removeUnit(boolean server, Unit unit) 
	{
		map.removeUnit(unit);
	}
	
	public void updateUnit(boolean server, Unit unit, Unit newProperties)
	{
		map.removeUnit(unit);
		map.addUnit(newProperties);
	}
	
	public void placeBuilding(boolean server, Building building) 
	{
		map.addBuilding(building);
	}
	
	public void removeBuilding(boolean server, Building building) 
	{
		map.removeBuilding(building);
	}
	
	public void updateBuilding(boolean server, Building building, Building newProperties) 
	{
		map.removeBuilding(building);
		map.addBuilding(newProperties);
	}
	
	public void playerLost(boolean server,Player player) 
	{
		player.setHasLost(true);
	}
	
	public void endTurn(boolean server)
	{
		this.playerTurn++;
		
		if (this.playerTurn > this.players.size())
		{
			this.playerTurn = 0;
			this.turn ++;
		}
	}
	
	public void gameOver(boolean server)
	{
		
	}
	
	
	//
	// High level commands
	//

	public ArrayList<Movement> listAllowedMovements(Unit unit) 
	{
		return null;
	}
	
	public void makeMovement(Unit unit, Movement move) 
	{
		
	}
	
	@SuppressWarnings("unused")
	private boolean checkMovement(Unit unit, Movement move) 
	{
		return false;
	}

	public String toString() {
		String str = "game_file_map\t1\n";
		str+= this.getName()+ "\n";
		str+= this.turn+ "\n";
		//PLAYER
		str+= this.players.size()+ "\t" +this.playerTurn+ "\n";
		for(Player p : this.players){
			str+= p+ "\n";
		}
		//MAP
		str+= this.map+ "\n";
		return str;
	}
}
